package com.jthinker.blog.service.impl;

import com.jthinker.blog.bean.entity.Category;
import com.jthinker.blog.bean.vo.CategoryTreeVO;
import com.jthinker.blog.dao.BaseDao;
import com.jthinker.blog.dao.CategoryDao;
import com.jthinker.blog.service.CategoryService;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * User: Gang Chen
 * Date: 2015/7/5 14:35
 */
@Service
public class CategoryServiceImpl extends BaseServiceImpl<Category, Long> implements CategoryService
{
    private static final Logger LOGGER = LoggerFactory.getLogger(CategoryService.class);

    private CategoryDao categoryDao;

    @Override
    @Autowired
    @Qualifier("categoryDao")
    protected void setBaseDao(BaseDao<Category, Long> baseDao)
    {
        this.baseDao = baseDao;
        categoryDao = (CategoryDao) baseDao;
    }

    @Cacheable(value = "categoryList")
    @Override
    public List<Category> listAll()
    {
        return super.listAll();
    }

    @Override
    public List<CategoryTreeVO> getTree()
    {
        List<Category> all = listAll();

        List<CategoryTreeVO> roots = new ArrayList<CategoryTreeVO>();
        Map<Long, CategoryTreeVO> allMap = new HashMap<Long, CategoryTreeVO>();

        try
        {
            for (Category category : all)
            {
                Long id = category.getId();
                CategoryTreeVO vo = new CategoryTreeVO();
                BeanUtils.copyProperties(vo, category);
                allMap.put(id, vo);
            }
        }
        catch (IllegalAccessException e)
        {
            LOGGER.error("{}", e);
        }
        catch (InvocationTargetException e)
        {
            LOGGER.error("{}", e);
        }

        for (Map.Entry<Long, CategoryTreeVO> entry : allMap.entrySet())
        {
            CategoryTreeVO node = entry.getValue();

            //根节点
            if (node.getParentId() == null || node.getParentId() == 0L)
            {
                roots.add(node);
            }
            else
            {
                CategoryTreeVO parent = allMap.get(node.getParentId());

                List<CategoryTreeVO> children = parent.getChildren();
                if (CollectionUtils.isEmpty(children))
                {
                    children = new ArrayList<CategoryTreeVO>();
                    parent.setChildren(children);
                }
                children.add(node);
            }
        }

        return roots;
    }

    @Cacheable(value = "categoryList", key = "#slug")
    @Override
    public Long getIdBySlug(String slug)
    {
        return categoryDao.getIdBySlug(slug);
    }

    @CacheEvict(value = "categoryList", allEntries = true)
    @Override
    public void merge(Category model)
    {
        super.merge(model);
    }

    @CacheEvict(value = "categoryList", allEntries = true)
    @Override
    public void delete(Long id)
    {
        super.delete(id);
    }
}
